// vSlidein.ts
import { Directive, DirectiveBinding, onMounted, onUnmounted } from 'vue';

const DISTANCE = 150;
const DURATION = 600;
const animationMap = new WeakMap<HTMLElement, Animation>();

const SlideInDirective: Directive = {
    beforeMount(el: HTMLElement, binding: DirectiveBinding) {
        // 初始时将元素定位到视图外
        el.style.transform = `translateY(${DISTANCE}px)`;
        el.style.transition = 'transform 0s'; // 禁用过渡效果，以避免初始位移时的动画
      
        // 创建 IntersectionObserver 来触发动画
        const ob = new IntersectionObserver(
          (entries) => {
            entries.forEach((entry) => {
              if (entry.isIntersecting) {
                // 重新启用过渡效果
                el.style.transition = `transform ${DURATION}ms cubic-bezier(0.695, 0.105, 0.415, 0.880)`; // 使用贝塞尔曲线
                // 当元素进入视口时，开始动画
                const animation = el.animate(
                  [
                    { opacity: 0, transform: `translateY(${DISTANCE}px)` },
                    { opacity: 1, transform: 'translateY(0)' },
                  ],
                  {
                    duration: DURATION,
                    fill: 'forwards',
                    easing: 'cubic-bezier(0.695, 0.105, 0.415, 0.880)' // 应用贝塞尔曲线
                  }
                );
                animationMap.set(el, animation);
                ob.unobserve(el); // 停止观察
              }
            });
          },
          {
            rootMargin: '150px',
            threshold: 0.01,
          }
        );
        ob.observe(el);
      },
  unmounted(el: HTMLElement) {
    // 取消动画并清理
    const animation = animationMap.get(el);
    if (animation) {
      animation.cancel();
    }
    animationMap.delete(el);
  },
};

export default SlideInDirective;